签名规则
1.签名支持SM3(推荐)和SHA256方式(不上送signType字段时,SM3),计算sign的输入数据为待签名字符串加上key(即:签名密钥),key由大华捷通平台分配。
2.在请求参数列表中,除去sign和空值的参数外,其他需要使用到的参数均为要签名的参数
生成待签名字符串
第一步:设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
特别注意以下重要规则:
(1).参数名ASCII码从小到大排序(字典序);
(2).如果参数的值为空不参与签名;
(3).参数名区分大小写;
(4).验证调用返回时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
(5).大华捷通平台接口可能增加字段,验证签名时必须支持增加的扩展字段
第二步:在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行SHA256运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。
//代码建议复制到开发工具中格式化一下,便于阅读
public static void gzh() throws UnsupportedEncodingException {
TreeMap treeMap = new TreeMap();
treeMap.put("version", "20191031");
treeMap.put("msgId", "4217");
treeMap.put("msgType", "");
treeMap.put("requestTimestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
treeMap.put("expireTime", "");
treeMap.put("merOrderId", "4217" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
treeMap.put("mid", mid);
treeMap.put("tid",tid);
treeMap.put("instMid", "MINIDEFAULT");
treeMap.put("attachedData","");
treeMap.put("orderDesc","");
treeMap.put("originalAmount", "");
treeMap.put("totalAmount", "1");
treeMap.put("notifyUrl", "http://ip:port/server/notify");
treeMap.put("signType", "SHA256");
treeMap.put("extend1","extend1");
treeMap.put("extend2","extend2");
treeMap.put("extend3","extend3");
treeMap.put("extend4","extend4");
StringBuffer sb = new StringBuffer();// 代签名的字符串
StringBuffer req = new StringBuffer();// 组织请求参数
for (String key : treeMap.keySet()) {
if (treeMap.get(key) != null && !"".equals(treeMap.get(key))) {
if (sb.length() == 0) {
sb.append(key + "=" + treeMap.get(key));
req.append(key + "=" + URLEncoder.encode(treeMap.get(key), "UTF-8"));
} else {
sb.append("&" + key + "=" + treeMap.get(key));
req.append("&" + key + "=" + URLEncoder.encode(treeMap.get(key), "UTF-8"));
}
}
}
System.out.println("待签名的字符串是:" + sb.toString());
String sign = "";
try {
sign = SM3Util.SHA256(sb.toString() + signKey);
} catch (Exception e) {
}
System.out.println("sign的值是:" + sign);
req.append("&sign=" + URLEncoder.encode(sign, "UTF-8"));// 将签名信息添加在请求参数后面
//TODO 此处应该使用http请求工具类发送get或者post请求,这里只是演示,直接拼接了get请求的url
System.out.println("小程序支付实际跳转的URL是:" + pay_url + req.toString());
}